<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: How to Use Background Subtraction Methods</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d9/df8/tutorial_root.html">OpenCV Tutorials</a></li><li class="navelem"><a class="el" href="../../d3/dd5/tutorial_table_of_content_other.html">Other tutorials (ml, objdetect, photo, stitching, video)</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">How to Use Background Subtraction Methods </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><b>Prev Tutorial:</b> <a class="el" href="../../d8/d19/tutorial_stitcher.html">High level stitching API (Stitcher class)</a></p>
<p><b>Next Tutorial:</b> <a class="el" href="../../d7/d00/tutorial_meanshift.html">Meanshift and Camshift</a></p>
<table class="doxtable">
<tr>
<th align="right"></th><th align="left"></th></tr>
<tr>
<td align="right">Original author </td><td align="left">Domenico Daniele Bloisi </td></tr>
<tr>
<td align="right">Compatibility </td><td align="left">OpenCV &gt;= 3.0 </td></tr>
</table>
<ul>
<li>Background subtraction (BS) is a common and widely used technique for generating a foreground mask (namely, a binary image containing the pixels belonging to moving objects in the scene) by using static cameras.</li>
<li><p class="startli">As the name suggests, BS calculates the foreground mask performing a subtraction between the current frame and a background model, containing the static part of the scene or, more in general, everything that can be considered as background given the characteristics of the observed scene.</p>
<div class="image">
<img src="../../Background_Subtraction_Tutorial_Scheme.png" alt="Background_Subtraction_Tutorial_Scheme.png"/>
</div>
</li>
<li><p class="startli">Background modeling consists of two main steps:</p><ol type="1">
<li>Background Initialization;</li>
<li>Background Update.</li>
</ol>
<p class="startli">In the first step, an initial model of the background is computed, while in the second step that model is updated in order to adapt to possible changes in the scene.</p>
</li>
<li>In this tutorial we will learn how to perform BS by using OpenCV.</li>
</ul>
<h2>Goals </h2>
<p>In this tutorial you will learn how to:</p>
<ol type="1">
<li>Read data from videos or image sequences by using <a class="el" href="../../d8/dfe/classcv_1_1VideoCapture.html">cv::VideoCapture</a> ;</li>
<li>Create and update the background model by using <a class="el" href="../../d7/df6/classcv_1_1BackgroundSubtractor.html">cv::BackgroundSubtractor</a> class;</li>
<li>Get and show the foreground mask by using <a class="el" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">cv::imshow</a> ;</li>
</ol>
<h3>Code</h3>
<p>In the following you can find the source code. We will let the user choose to process either a video file or a sequence of images.</p>
<p>We will use <a class="el" href="../../d7/d7b/classcv_1_1BackgroundSubtractorMOG2.html">cv::BackgroundSubtractorMOG2</a> in this sample, to generate the foreground mask.</p>
<p>The results as well as the input data are shown on the screen.</p>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/video/bg_sub.cpp">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;sstream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d6/d87/imgcodecs_8hpp.html">opencv2/imgcodecs.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d1/d4f/imgproc_2include_2opencv2_2imgproc_8hpp.html">opencv2/imgproc.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../dc/d3d/videoio_8hpp.html">opencv2/videoio.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d4/dd5/highgui_8hpp.html">opencv2/highgui.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d0/d1c/video_2include_2opencv2_2video_8hpp.html">opencv2/video.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* params</div><div class="line">    = <span class="stringliteral">&quot;{ help h         |           | Print usage }&quot;</span></div><div class="line">      <span class="stringliteral">&quot;{ input          | vtest.avi | Path to a video or a sequence of image }&quot;</span></div><div class="line">      <span class="stringliteral">&quot;{ algo           | MOG2      | Background subtraction method (KNN, MOG2) }&quot;</span>;</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[])</div><div class="line">{</div><div class="line">    <a class="code" href="../../d0/d2e/classcv_1_1CommandLineParser.html">CommandLineParser</a> parser(argc, argv, params);</div><div class="line">    parser.about( <span class="stringliteral">&quot;This program shows how to use background subtraction methods provided by &quot;</span></div><div class="line">                  <span class="stringliteral">&quot; OpenCV. You can process both videos and images.\n&quot;</span> );</div><div class="line">    <span class="keywordflow">if</span> (parser.has(<span class="stringliteral">&quot;help&quot;</span>))</div><div class="line">    {</div><div class="line">        <span class="comment">//print help information</span></div><div class="line">        parser.printMessage();</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">//create Background Subtractor objects</span></div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga6395ca871a678020c4a31fadf7e8cc63">Ptr&lt;BackgroundSubtractor&gt;</a> pBackSub;</div><div class="line">    <span class="keywordflow">if</span> (parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;algo&quot;</span>) == <span class="stringliteral">&quot;MOG2&quot;</span>)</div><div class="line">        pBackSub = <a class="code" href="../../de/de1/group__video__motion.html#ga2beb2dee7a073809ccec60f145b6b29c">createBackgroundSubtractorMOG2</a>();</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">        pBackSub = <a class="code" href="../../de/de1/group__video__motion.html#gac9be925771f805b6fdb614ec2292006d">createBackgroundSubtractorKNN</a>();</div><div class="line"></div><div class="line">    <a class="code" href="../../d8/dfe/classcv_1_1VideoCapture.html">VideoCapture</a> capture( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;input&quot;</span>) ) );</div><div class="line">    <span class="keywordflow">if</span> (!capture.isOpened()){</div><div class="line">        <span class="comment">//error in opening the video input</span></div><div class="line">        cerr &lt;&lt; <span class="stringliteral">&quot;Unable to open: &quot;</span> &lt;&lt; parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;input&quot;</span>) &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> frame, fgMask;</div><div class="line">    <span class="keywordflow">while</span> (<span class="keyword">true</span>) {</div><div class="line">        capture &gt;&gt; frame;</div><div class="line">        <span class="keywordflow">if</span> (frame.empty())</div><div class="line">            <span class="keywordflow">break</span>;</div><div class="line"></div><div class="line">        <span class="comment">//update the background model</span></div><div class="line">        pBackSub-&gt;apply(frame, fgMask);</div><div class="line"></div><div class="line">        <span class="comment">//get the frame number and write it on the current frame</span></div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga07d2f74cadcf8e305e810ce8eed13bc9">rectangle</a>(frame, <a class="code" href="../../db/d4e/classcv_1_1Point__.html">cv::Point</a>(10, 2), <a class="code" href="../../db/d4e/classcv_1_1Point__.html">cv::Point</a>(100,20),</div><div class="line">                  <a class="code" href="../../d1/da0/classcv_1_1Scalar__.html">cv::Scalar</a>(255,255,255), -1);</div><div class="line">        stringstream ss;</div><div class="line">        ss &lt;&lt; capture.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704da6223452891755166a4fd5173ea257068">CAP_PROP_POS_FRAMES</a>);</div><div class="line">        <span class="keywordtype">string</span> frameNumberString = ss.str();</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576">putText</a>(frame, frameNumberString.c_str(), <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">cv::Point</a>(15, 15),</div><div class="line">                <a class="code" href="../../d6/d6e/group__imgproc__draw.html#gga0f9314ea6e35f99bb23f29567fc16e11afff8b973668df2e4028dddc5274310c9">FONT_HERSHEY_SIMPLEX</a>, 0.5 , <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">cv::Scalar</a>(0,0,0));</div><div class="line"></div><div class="line">        <span class="comment">//show the current frame and the fg masks</span></div><div class="line">        <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;Frame&quot;</span>, frame);</div><div class="line">        <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;FG Mask&quot;</span>, fgMask);</div><div class="line"></div><div class="line">        <span class="comment">//get the input from the keyboard</span></div><div class="line">        <span class="keywordtype">int</span> keyboard = <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>(30);</div><div class="line">        <span class="keywordflow">if</span> (keyboard == <span class="charliteral">&#39;q&#39;</span> || keyboard == 27)</div><div class="line">            <span class="keywordflow">break</span>;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment -->  </div> </li>
</ul>
 <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/video/background_subtraction/BackgroundSubtractionDemo.java">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="keyword">import</span> org.opencv.core.Core;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Mat;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Point;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Scalar;</div><div class="line"><span class="keyword">import</span> org.opencv.highgui.HighGui;</div><div class="line"><span class="keyword">import</span> org.opencv.imgproc.Imgproc;</div><div class="line"><span class="keyword">import</span> org.opencv.video.BackgroundSubtractor;</div><div class="line"><span class="keyword">import</span> org.opencv.video.Video;</div><div class="line"><span class="keyword">import</span> org.opencv.videoio.VideoCapture;</div><div class="line"><span class="keyword">import</span> org.opencv.videoio.Videoio;</div><div class="line"></div><div class="line"><span class="keyword">class </span>BackgroundSubtraction {</div><div class="line">    <span class="keyword">public</span> <span class="keywordtype">void</span> run(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> input = args.length &gt; 0 ? args[0] : <span class="stringliteral">&quot;../data/vtest.avi&quot;</span>;</div><div class="line">        <span class="keywordtype">boolean</span> useMOG2 = args.length &gt; 1 ? args[1] == <span class="stringliteral">&quot;MOG2&quot;</span> : <span class="keyword">true</span>;</div><div class="line"></div><div class="line">        <a class="code" href="../../d4/d55/group__gapi__video.html#gaab6a9c8473dbb256ec55865ee189b417">BackgroundSubtractor</a> backSub;</div><div class="line">        <span class="keywordflow">if</span> (useMOG2) {</div><div class="line">            backSub = Video.createBackgroundSubtractorMOG2();</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            backSub = Video.createBackgroundSubtractorKNN();</div><div class="line">        }</div><div class="line"></div><div class="line">        VideoCapture capture = <span class="keyword">new</span> VideoCapture(input);</div><div class="line">        <span class="keywordflow">if</span> (!capture.isOpened()) {</div><div class="line">            System.err.println(<span class="stringliteral">&quot;Unable to open: &quot;</span> + input);</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line"></div><div class="line">        Mat frame = <span class="keyword">new</span> Mat(), fgMask = <span class="keyword">new</span> Mat();</div><div class="line">        <span class="keywordflow">while</span> (<span class="keyword">true</span>) {</div><div class="line">            capture.read(frame);</div><div class="line">            <span class="keywordflow">if</span> (frame.empty()) {</div><div class="line">                <span class="keywordflow">break</span>;</div><div class="line">            }</div><div class="line"></div><div class="line">            <span class="comment">// update the background model</span></div><div class="line">            backSub.apply(frame, fgMask);</div><div class="line"></div><div class="line">            <span class="comment">// get the frame number and write it on the current frame</span></div><div class="line">            Imgproc.rectangle(frame, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(10, 2), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(100, 20), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(255, 255, 255), -1);</div><div class="line">            <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> frameNumberString = <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>.format(<span class="stringliteral">&quot;%d&quot;</span>, (<span class="keywordtype">int</span>)capture.get(Videoio.CAP_PROP_POS_FRAMES));</div><div class="line">            Imgproc.putText(frame, frameNumberString, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(15, 15), Core.FONT_HERSHEY_SIMPLEX, 0.5,</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(0, 0, 0));</div><div class="line"></div><div class="line">            <span class="comment">// show the current frame and the fg masks</span></div><div class="line">            HighGui.imshow(<span class="stringliteral">&quot;Frame&quot;</span>, frame);</div><div class="line">            HighGui.imshow(<span class="stringliteral">&quot;FG Mask&quot;</span>, fgMask);</div><div class="line"></div><div class="line">            <span class="comment">// get the input from the keyboard</span></div><div class="line">            <span class="keywordtype">int</span> keyboard = HighGui.waitKey(30);</div><div class="line">            <span class="keywordflow">if</span> (keyboard == <span class="charliteral">&#39;q&#39;</span> || keyboard == 27) {</div><div class="line">                <span class="keywordflow">break</span>;</div><div class="line">            }</div><div class="line">        }</div><div class="line"></div><div class="line">        HighGui.waitKey();</div><div class="line">        System.exit(0);</div><div class="line">    }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">class </span>BackgroundSubtractionDemo {</div><div class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keywordtype">void</span> main(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <span class="comment">// Load the native OpenCV library</span></div><div class="line">        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);</div><div class="line"></div><div class="line">        <span class="keyword">new</span> BackgroundSubtraction().run(args);</div><div class="line">    }</div><div class="line">}</div></div><!-- fragment -->  </div> </li>
</ul>
 <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/video/background_subtraction/bg_sub.py">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> print_function</div><div class="line"><span class="keyword">import</span> cv2 <span class="keyword">as</span> cv</div><div class="line"><span class="keyword">import</span> argparse</div><div class="line"></div><div class="line">parser = argparse.ArgumentParser(description=<span class="stringliteral">&#39;This program shows how to use background subtraction methods provided by \</span></div><div class="line"><span class="stringliteral">                                              OpenCV. You can process both videos and images.&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input&#39;</span>, type=str, help=<span class="stringliteral">&#39;Path to a video or a sequence of image.&#39;</span>, default=<span class="stringliteral">&#39;vtest.avi&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--algo&#39;</span>, type=str, help=<span class="stringliteral">&#39;Background subtraction method (KNN, MOG2).&#39;</span>, default=<span class="stringliteral">&#39;MOG2&#39;</span>)</div><div class="line">args = parser.parse_args()</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordflow">if</span> args.algo == <span class="stringliteral">&#39;MOG2&#39;</span>:</div><div class="line">    backSub = <a class="code" href="../../de/de1/group__video__motion.html#ga2beb2dee7a073809ccec60f145b6b29c">cv.createBackgroundSubtractorMOG2</a>()</div><div class="line"><span class="keywordflow">else</span>:</div><div class="line">    backSub = <a class="code" href="../../de/de1/group__video__motion.html#gac9be925771f805b6fdb614ec2292006d">cv.createBackgroundSubtractorKNN</a>()</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">capture = <a class="code" href="../../d8/dfe/classcv_1_1VideoCapture.html">cv.VideoCapture</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga4a37595bcd267558bd6c176c7307f050">cv.samples.findFileOrKeep</a>(args.input))</div><div class="line"><span class="keywordflow">if</span> <span class="keywordflow">not</span> capture.isOpened():</div><div class="line">    <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Unable to open: &#39;</span> + args.input)</div><div class="line">    exit(0)</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordflow">while</span> <span class="keyword">True</span>:</div><div class="line">    ret, frame = capture.read()</div><div class="line">    <span class="keywordflow">if</span> frame <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">        <span class="keywordflow">break</span></div><div class="line"></div><div class="line">    </div><div class="line">    fgMask = backSub.apply(frame)</div><div class="line">    </div><div class="line"></div><div class="line">    </div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#gac865734d137287c0afb7682ff7b3db23">cv.rectangle</a>(frame, (10, 2), (100,20), (255,255,255), -1)</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576">cv.putText</a>(frame, str(capture.get(cv.CAP_PROP_POS_FRAMES)), (15, 15),</div><div class="line">               cv.FONT_HERSHEY_SIMPLEX, 0.5 , (0,0,0))</div><div class="line">    </div><div class="line"></div><div class="line">    </div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;Frame&#39;</span>, frame)</div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;FG Mask&#39;</span>, fgMask)</div><div class="line">    </div><div class="line"></div><div class="line">    keyboard = <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>(30)</div><div class="line">    <span class="keywordflow">if</span> keyboard == <span class="stringliteral">&#39;q&#39;</span> <span class="keywordflow">or</span> keyboard == 27:</div><div class="line">        <span class="keywordflow">break</span></div></div><!-- fragment -->  </div> </li>
</ul>
<h2>Explanation </h2>
<p>We discuss the main parts of the code above:</p>
<ul>
<li>A <a class="el" href="../../d7/df6/classcv_1_1BackgroundSubtractor.html">cv::BackgroundSubtractor</a> object will be used to generate the foreground mask. In this example, default parameters are used, but it is also possible to declare specific parameters in the create function.</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <span class="comment">//create Background Subtractor objects</span></div><div class="line">    Ptr&lt;BackgroundSubtractor&gt; pBackSub;</div><div class="line">    <span class="keywordflow">if</span> (parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;algo&quot;</span>) == <span class="stringliteral">&quot;MOG2&quot;</span>)</div><div class="line">        pBackSub = <a class="code" href="../../de/de1/group__video__motion.html#ga2beb2dee7a073809ccec60f145b6b29c">createBackgroundSubtractorMOG2</a>();</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">        pBackSub = <a class="code" href="../../de/de1/group__video__motion.html#gac9be925771f805b6fdb614ec2292006d">createBackgroundSubtractorKNN</a>();</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <a class="code" href="../../d4/d55/group__gapi__video.html#gaab6a9c8473dbb256ec55865ee189b417">BackgroundSubtractor</a> backSub;</div><div class="line">        <span class="keywordflow">if</span> (useMOG2) {</div><div class="line">            backSub = Video.createBackgroundSubtractorMOG2();</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            backSub = Video.createBackgroundSubtractorKNN();</div><div class="line">        }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line"><span class="comment">#create Background Subtractor objects</span></div><div class="line"><span class="keywordflow">if</span> args.algo == <span class="stringliteral">&#39;MOG2&#39;</span>:</div><div class="line">    backSub = <a class="code" href="../../de/de1/group__video__motion.html#ga2beb2dee7a073809ccec60f145b6b29c">cv.createBackgroundSubtractorMOG2</a>()</div><div class="line"><span class="keywordflow">else</span>:</div><div class="line">    backSub = <a class="code" href="../../de/de1/group__video__motion.html#gac9be925771f805b6fdb614ec2292006d">cv.createBackgroundSubtractorKNN</a>()</div></div><!-- fragment --> </div> <ul>
<li>A <a class="el" href="../../d8/dfe/classcv_1_1VideoCapture.html">cv::VideoCapture</a> object is used to read the input video or input images sequence.</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    VideoCapture capture( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;input&quot;</span>) ) );</div><div class="line">    <span class="keywordflow">if</span> (!capture.isOpened()){</div><div class="line">        <span class="comment">//error in opening the video input</span></div><div class="line">        cerr &lt;&lt; <span class="stringliteral">&quot;Unable to open: &quot;</span> &lt;&lt; parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;input&quot;</span>) &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        VideoCapture capture = <span class="keyword">new</span> VideoCapture(input);</div><div class="line">        <span class="keywordflow">if</span> (!capture.isOpened()) {</div><div class="line">            System.err.println(<span class="stringliteral">&quot;Unable to open: &quot;</span> + input);</div><div class="line">            System.exit(0);</div><div class="line">        }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">capture = <a class="code" href="../../d8/dfe/classcv_1_1VideoCapture.html">cv.VideoCapture</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga4a37595bcd267558bd6c176c7307f050">cv.samples.findFileOrKeep</a>(args.input))</div><div class="line"><span class="keywordflow">if</span> <span class="keywordflow">not</span> capture.isOpened():</div><div class="line">    <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Unable to open: &#39;</span> + args.input)</div><div class="line">    exit(0)</div></div><!-- fragment --> </div> <ul>
<li>Every frame is used both for calculating the foreground mask and for updating the background. If you want to change the learning rate used for updating the background model, it is possible to set a specific learning rate by passing a parameter to the <code>apply</code> method.</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">        <span class="comment">//update the background model</span></div><div class="line">        pBackSub-&gt;apply(frame, fgMask);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">            <span class="comment">// update the background model</span></div><div class="line">            backSub.apply(frame, fgMask);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">    <span class="comment">#update the background model</span></div><div class="line">    fgMask = backSub.apply(frame)</div></div><!-- fragment --> </div> <ul>
<li>The current frame number can be extracted from the <a class="el" href="../../d8/dfe/classcv_1_1VideoCapture.html">cv::VideoCapture</a> object and stamped in the top left corner of the current frame. A white rectangle is used to highlight the black colored frame number.</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">        <span class="comment">//get the frame number and write it on the current frame</span></div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga07d2f74cadcf8e305e810ce8eed13bc9">rectangle</a>(frame, <a class="code" href="../../db/d4e/classcv_1_1Point__.html">cv::Point</a>(10, 2), <a class="code" href="../../db/d4e/classcv_1_1Point__.html">cv::Point</a>(100,20),</div><div class="line">                  <a class="code" href="../../d1/da0/classcv_1_1Scalar__.html">cv::Scalar</a>(255,255,255), -1);</div><div class="line">        stringstream ss;</div><div class="line">        ss &lt;&lt; capture.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704da6223452891755166a4fd5173ea257068">CAP_PROP_POS_FRAMES</a>);</div><div class="line">        <span class="keywordtype">string</span> frameNumberString = ss.str();</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576">putText</a>(frame, frameNumberString.c_str(), <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">cv::Point</a>(15, 15),</div><div class="line">                <a class="code" href="../../d6/d6e/group__imgproc__draw.html#gga0f9314ea6e35f99bb23f29567fc16e11afff8b973668df2e4028dddc5274310c9">FONT_HERSHEY_SIMPLEX</a>, 0.5 , <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">cv::Scalar</a>(0,0,0));</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">            <span class="comment">// get the frame number and write it on the current frame</span></div><div class="line">            Imgproc.rectangle(frame, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(10, 2), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(100, 20), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(255, 255, 255), -1);</div><div class="line">            <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> frameNumberString = <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>.format(<span class="stringliteral">&quot;%d&quot;</span>, (<span class="keywordtype">int</span>)capture.get(Videoio.CAP_PROP_POS_FRAMES));</div><div class="line">            Imgproc.putText(frame, frameNumberString, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(15, 15), Core.FONT_HERSHEY_SIMPLEX, 0.5,</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(0, 0, 0));</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">    <span class="comment">#get the frame number and write it on the current frame</span></div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#gac865734d137287c0afb7682ff7b3db23">cv.rectangle</a>(frame, (10, 2), (100,20), (255,255,255), -1)</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576">cv.putText</a>(frame, str(capture.get(cv.CAP_PROP_POS_FRAMES)), (15, 15),</div><div class="line">               cv.FONT_HERSHEY_SIMPLEX, 0.5 , (0,0,0))</div></div><!-- fragment --> </div> <ul>
<li>We are ready to show the current input frame and the results.</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">        <span class="comment">//show the current frame and the fg masks</span></div><div class="line">        <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;Frame&quot;</span>, frame);</div><div class="line">        <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;FG Mask&quot;</span>, fgMask);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">            <span class="comment">// show the current frame and the fg masks</span></div><div class="line">            HighGui.imshow(<span class="stringliteral">&quot;Frame&quot;</span>, frame);</div><div class="line">            HighGui.imshow(<span class="stringliteral">&quot;FG Mask&quot;</span>, fgMask);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">    <span class="comment">#show the current frame and the fg masks</span></div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;Frame&#39;</span>, frame)</div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;FG Mask&#39;</span>, fgMask)</div></div><!-- fragment --> </div> <h2>Results </h2>
<ul>
<li><p class="startli">With the <code>vtest.avi</code> video, for the following frame:</p>
<div class="image">
<img src="../../Background_Subtraction_Tutorial_frame.jpg" alt="Background_Subtraction_Tutorial_frame.jpg"/>
</div>
<p class="startli">The output of the program will look as the following for MOG2 method (gray areas are detected shadows):</p>
<div class="image">
<img src="../../Background_Subtraction_Tutorial_result_MOG2.jpg" alt="Background_Subtraction_Tutorial_result_MOG2.jpg"/>
</div>
<p class="startli">The output of the program will look as the following for the KNN method (gray areas are detected shadows):</p>
<div class="image">
<img src="../../Background_Subtraction_Tutorial_result_KNN.jpg" alt="Background_Subtraction_Tutorial_result_KNN.jpg"/>
</div>
</li>
</ul>
<h2>References </h2>
<ul>
<li><a href="https://web.archive.org/web/20140418093037/http://bmc.univ-bpclermont.fr/">Background Models Challenge (BMC) website</a></li>
<li>A Benchmark Dataset for Foreground/Background Extraction <a class="el" href="../../d0/de3/citelist.html#CITEREF_vacavant2013benchmark">[255]</a> </li>
</ul>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:37 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
